package cn.xiaolang.thread.juc;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

@Slf4j
public class ExecutorsCompareSample {

    private static void runWork(ExecutorService threadPool) {
        for (int i = 1; i < 5; i++) {
            final int taskID = i;
            threadPool.execute(() -> {
                for (int j = 1; j < 5; j++) {
                    try {
                        // 为了测试出效果，让每次任务执行都需要一定时间
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        log.error("exec ex:", e);
                        Thread.currentThread().interrupt();
                    }
                    log.info("第{}个任务的第{}次执行,执行线程：{}", taskID, j, Thread.currentThread().getName());
                }
            });

        }
        threadPool.shutdown();
    }

    @Test
    public void testScheduledThreadPoolFixedRate() throws InterruptedException {
        // 创建一个定时周期的线程池
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        log.info("start test ScheduledThreadPoolFixedRate");
        scheduledThreadPool.scheduleAtFixedRate(() ->
                       log.info("delay 1 seconds,and execute every 3 seconds!!!"),
                1, 3, TimeUnit.SECONDS);
        Thread.sleep(9000);
        scheduledThreadPool.shutdown();
    }

    @Test
    public void testScheduledThreadPool() throws InterruptedException {

        // 效果类似于Timer定时器
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
        // 🔥任务顺序执行完成所有次数(单个线程)
        runWork(scheduledThreadPool);
        // 模拟等待，等候子线程执行完任务
        TimeUnit.SECONDS.sleep(3);
    }

    @Test
    public void testFixedThreadPool() throws InterruptedException {
        // 创建可以容纳3个线程的线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        // 任务随机执行次数顺序执行(🔥单个线程内顺序执行某个任务的所有次数)
        runWork(fixedThreadPool);
        // 模拟等待，等候子线程执行完任务
        TimeUnit.SECONDS.sleep(3);
    }

    @Test
    public void testCachedThreadPool() throws InterruptedException {
        // 线程池的大小会根据执行的任务数动态分配
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        // 任务随机执行次数顺序执行(🔥单个线程内顺序执行某个任务的所有次数)
        runWork(cachedThreadPool);
        // 模拟等待，等候子线程执行完任务
        TimeUnit.SECONDS.sleep(3);
    }

    @Test
    public void testSingleThreadPool() throws InterruptedException {
        // 创建单个线程的线程池，如果当前线程在执行任务时突然中断，则会创建一个新的线程替代它继续执行任务
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        // 🔥任务顺序执行完成所有次数(单个线程)
        runWork(singleThreadPool);
        // 模拟等待，等候子线程执行完任务
        TimeUnit.SECONDS.sleep(3);
    }


}
